package org.bangumibuddy.parser.impl;

import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEntry;
import com.turn.ttorrent.common.TorrentMetadata;
import com.turn.ttorrent.common.TorrentUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.bangumibuddy.parser.AnimeMetaParser;
import org.bangumibuddy.parser.TorrentParser;
import org.bangumibuddy.parser.factory.AnimeMetaParserFactory;
import org.bangumibuddy.pojo.anime.AnimeMetaData;
import org.bangumibuddy.pojo.TorrentFile;

import java.io.InputStream;
import java.net.ConnectException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Slf4j
public class DefaultTorrentParser implements TorrentParser {
    ExecutorService executor = Executors.newFixedThreadPool(5); // 创建一个固定大小的线程池

    AnimeMetaParser animeMetaParser = AnimeMetaParserFactory.create();

    @Override
    public List<TorrentFile> getTorrentFiles(List<String> torrentURLs) {
        List<Future<TorrentFile>> futures = new ArrayList<>();

        for (String torrentURL : torrentURLs) {
            // 提交任务到线程池
            Future<TorrentFile> future = executor.submit(() -> {
                TorrentMetadata metadata = getTorrent(torrentURL);
                return InternalGetTorrentFile(metadata,metadata.getDirectoryName(),torrentURL);
            });
            futures.add(future);
        }

        List<TorrentFile> torrentFiles = new ArrayList<>();
        for (Future<TorrentFile> future : futures) {
            try {
                torrentFiles.add(future.get()); // 获取并添加Future的结果
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        return torrentFiles;
    }

    private TorrentFile InternalGetTorrentFile(TorrentMetadata metadata,String fileName,String url)
    {
        TorrentFile torrentFile = new TorrentFile();
        torrentFile.setHash(metadata.getHexInfoHash().toLowerCase());
        torrentFile.setUrl(url);
        torrentFile.setTorrentName(fileName);
        torrentFile.setIsCollection(metadata.getFiles().size() > 1);

        torrentFile.setSize(formatSize((long) metadata.getPiecesCount() * (long) metadata.getPieceLength()));
        torrentFile.setIsSelected(true);

        AnimeMetaData parse = animeMetaParser.parse(fileName);
        if (parse == null) {
            setFileExtension(torrentFile, metadata);
            log.error("AnimeMetaData parse failed: {}", fileName);
            return torrentFile;
        }

        torrentFile.setSavePath(parse.getSavePath());
        torrentFile.setFileName(parse.getSaveFileName());
        torrentFile.setGroup(parse.getGroup());
        torrentFile.setEpisode(parse.getEpisode());
        setFileExtension(torrentFile, metadata);

        return torrentFile;
    }

    @Override
    public List<TorrentFile> getTorrentFilesByEntries(List<SyndEntry> entries) {
        List<Future<TorrentFile>> futures = new ArrayList<>();

        for (SyndEntry entry : entries) {
            // 提交任务到线程池
            Future<TorrentFile> future = executor.submit(() -> {
                SyndEnclosure enclosure = (SyndEnclosure) entry.getEnclosures().get(0);
                TorrentMetadata metadata = getTorrent(enclosure.getUrl());

                return InternalGetTorrentFile(metadata,entry.getTitle(),enclosure.getUrl());
            });
            futures.add(future);
        }

        List<TorrentFile> torrentFiles = new ArrayList<>();
        for (Future<TorrentFile> future : futures) {
            try {
                torrentFiles.add(future.get()); // 获取并添加Future的结果
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        return torrentFiles;
    }

    @SneakyThrows
    private TorrentMetadata getTorrent(String torrentURL) {

        try {
            URL url = new URL(torrentURL);
            // 打开一个到该URL的输入流
            InputStream in = url.openStream();
            // 将输入流的内容复制到临时文件中
            TorrentMetadata metadata = new com.turn.ttorrent.common.TorrentParser().parse(in.readAllBytes());
            return metadata;
        } catch (UnknownHostException e) {
            log.error("UnknownHostException: {}", torrentURL);
            return null;
        } catch (ConnectException e) {
            log.error("ConnectException: {}", torrentURL);
            return null;
        }
    }

    private void setFileExtension(TorrentFile torrentFile, TorrentMetadata metadata) {
        if (torrentFile.getIsCollection()) {
            torrentFile.setExtension("Collection");
        } else {
            // 获取文件后缀
            String fileExtension = "";
            String filename = TorrentUtils.getTorrentFileNames(metadata).get(0);
            int lastDotIndex = filename.lastIndexOf('.');
            if (lastDotIndex > 0) {
                fileExtension = filename.substring(lastDotIndex + 1);
            }
            torrentFile.setExtension(fileExtension);
            if(!torrentFile.getFileName().contains(torrentFile.getExtension()))
            {
                torrentFile.setFileName(torrentFile.getFileName()+"."+torrentFile.getExtension());
            }
        }
    }

    public String formatSize(long bytes) {
        String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
        int unitIndex = (int) (Math.log10(bytes) / 3);
        double unitValue = bytes / Math.pow(1024, unitIndex);
        return String.format("%.2f %s", unitValue, units[unitIndex]);
    }
}
